﻿using System;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using iLangl.Model;
using iLangl.BusinessModel.DAL;
using iLangl.BusinessModel.Actions.Common;

namespace iLangl.BusinessModel.Managers
{
	public class SynchronizationManager
	{
		#region Singelton Pattern
		private SynchronizationManager()
		{
		}

		private static SynchronizationManager instance;
		private static object mutex = new object();
		/// <summary>
		/// The instance of the SynchronizationManager.
		/// </summary>
		public static SynchronizationManager Instance
		{
			get
			{
				if (instance == null)
				{
					lock (mutex)
					{
						if (instance == null)
						{
							instance = new SynchronizationManager();
						}
					}
				}
				return instance;
			}
		}
		#endregion

		public void Synchronize()
		{
			SyncedMutliWaysData synced = DALFacade.Instance.SynchronizationDAL.SyncObjects();

			IList<SyncedOneWayData> syncedList = synced.PrepareDataToSend();

			// Async Pushing
			Parallel.ForEach(syncedList, PushAction);
		}


		public void SyncData(SyncedOneWayData result)
		{
			PluginLicense pl = PluginManager.Instance.GetLicense(result.Subscriber);



			if ((result.Companies != null) && (result.Companies.Length > 0))
			{
				foreach (Company company in result.Companies)
				{
					CompanyManager.Instance.UpdateCompanyInfo(company);
					CompanyManager.Instance.AddSubscriber(company, pl, false);
				}
			}

			if ((result.Projects != null) && (result.Projects.Length > 0))
			{
				
				foreach (Project project in result.Projects)
				{
					ProjectManager.Instance.ToLocalLanguagesMapping(project, pl);
					ProjectManager.Instance.UpdateProject(project);
					ProjectManager.Instance.AddSubscriber(project, pl, false);
				}
			}

			if ((result.Alerts != null) && (result.Alerts.Length > 0))
			{
				foreach (ISerializedAlert alert in result.Alerts)
				{
					DALFacade.Instance.AlertDAL.SaveAlert(alert, null);
				}
			}
		}


		public void PushAction(SyncedOneWayData data)
		{
			PushAction action = new PushAction(data);
			//Find Plugin License
			PluginLicense license = PluginManager.Instance.GetLicense(data.Subscriber);
			ActionManager.Instance.PrepareAction(license, action);

			action.Send();
		}

		public void MarkAsSynced(SyncedOneWayData data)
		{
			DALFacade.Instance.SynchronizationDAL.MarkAsSynced(data);
		}

		public void AddSubscriber(eEntityType type, String objectId, PluginLicense license, bool isNeedToSync)
		{
			//We not add subscribers for plugin where push service is not available
			if (!license.Plugin.IsPushingEnabled)
			{
				return;
			}

			DALFacade.Instance.SynchronizationDAL.AddSubscriber(type, objectId, license.ID, isNeedToSync);
		}

		public void RemoveSubscriber(eEntityType type, String objectId)
		{
			DALFacade.Instance.SynchronizationDAL.RemoveSubscriber(type, objectId);
		}

		public void RemoveSubscriber(eEntityType type, String objectId, String subscriberId)
		{
			DALFacade.Instance.SynchronizationDAL.RemoveSubscriber(type, objectId, subscriberId);
		}

	}
}
